package com.alibaba.csp.sentinel.dashboard.config;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity; // 添加导入
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; // 添加导入
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; // 添加导入
import com.alibaba.csp.sentinel.dashboard.domain.cluster.ClusterGroupEntity;
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ClusterClientConfig;
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerFlowConfig;
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerTransportConfig;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; // 添加导入

import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 * packageName com.alibaba.csp.sentinel.dashboard.config.NacosConfig
 *
 * @author liudonghai
 * @version JDK 11
 * @date 2025/9/12
 * @description nacos配置类
 */
@Configuration // 添加注解，确保这是一个配置类
public class NacosConfig {
    @Value("${nacos.server-addr:${nacos.host:localhost:8848}}")
    private String serverAddr;

    @Value("${nacos.namespace:}")
    private String namespace;

    @Value("${nacos.username:}")
    private String username;

    @Value("${nacos.password:}")
    private String password;

    @Value("${nacos.group-id:SENTINEL_GROUP}")
    private String groupId;

    @Bean
    public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, FlowRuleEntity.class);
    }

    @Bean
    public Converter<List<SystemRuleEntity>, String> systemRuleEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, List<SystemRuleEntity>> systemRuleEntityDecoder() {
        return s -> JSON.parseArray(s, SystemRuleEntity.class);
    }

    // 添加降级规则的编解码器
    @Bean
    public Converter<List<DegradeRuleEntity>, String> degradeRuleEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, List<DegradeRuleEntity>> degradeRuleEntityDecoder() {
        return s -> JSON.parseArray(s, DegradeRuleEntity.class);
    }

    // 添加授权规则的编解码器
    @Bean
    public Converter<List<AuthorityRuleEntity>, String> authorityRuleEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, List<AuthorityRuleEntity>> authorityRuleEntityDecoder() {
        return s -> JSON.parseArray(s, AuthorityRuleEntity.class);
    }

    // 添加热点参数规则的编解码器
    @Bean
    public Converter<List<ParamFlowRuleEntity>, String> paramFlowRuleEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, List<ParamFlowRuleEntity>> paramFlowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, ParamFlowRuleEntity.class);
    }

    // 添加集群映射的编解码器
    @Bean
    public Converter<Set<ClusterGroupEntity>, String> clusterMapEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, Set<ClusterGroupEntity>> clusterMapEntityDecoder() {
        return s -> JSON.parseObject(s, new TypeReference<Set<ClusterGroupEntity>>() {});
    }

    @Bean
    public Converter<ServerTransportConfig, String> clusterServerTransportConfigEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, ServerTransportConfig> clusterServerTransportConfigDecoder() {
        return s -> JSON.parseObject(s, ServerTransportConfig.class);
    }

    @Bean
    public Converter<ServerFlowConfig, String> clusterServerFlowConfigEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, ServerFlowConfig> clusterServerFlowConfigDecoder() {
        return s -> JSON.parseObject(s, ServerFlowConfig.class);
    }

    @Bean
    public Converter<ClusterClientConfig, String> clusterClientConfigEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, ClusterClientConfig> clusterClientConfigDecoder() {
        return s -> JSON.parseObject(s, ClusterClientConfig.class);
    }

    @Bean
    public ConfigService nacosConfigService() throws Exception {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        if (!namespace.isEmpty()) {
            properties.put(PropertyKeyConst.NAMESPACE, namespace);
        }
        if (!username.isEmpty()) {
            properties.put(PropertyKeyConst.USERNAME, username);
        }
        if (!password.isEmpty()) {
            properties.put(PropertyKeyConst.PASSWORD, password);
        }
        ConfigService configService = ConfigFactory.createConfigService(properties);
        if(configService!=null && configService.getServerStatus().equals("UP")) {
            return configService;
        }
        configService = NacosFactory.createConfigService(properties);
        if(configService!=null && configService.getServerStatus().equals("UP")) {
            return configService;
        }
        System.out.println("Failed to connect to Nacos server: {"+serverAddr+"}");
        return null;
    }

    // 提供 getter 方法，供其他地方使用 groupId
    public String getGroupId() {
        return groupId;
    }
}
